Maximum Sharpe Ratio Portfolio#
import numpy as np
from plotly.io import show
from sklearn.model_selection import train_test_split
from skfolio import Population, RiskMeasure
from skfolio.datasets import load_sp500_dataset
from skfolio.optimization import InverseVolatility, MeanRisk, ObjectiveFunction
from skfolio.preprocessing import prices_to_returns
Data Preparation#
price = load_sp500_dataset()
price.head()
| AAPL | AMD | BAC | BBY | CVX | GE | HD | JNJ | JPM | KO | LLY | MRK | MSFT | PEP | PFE | PG | RRC | UNH | WMT | XOM | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | ||||||||||||||||||||
| 1990-01-02 | 0.264 | 4.125 | 4.599 | 0.144 | 4.991 | 14.391 | 1.117 | 3.438 | 3.394 | 2.235 | 6.658 | 4.215 | 0.384 | 4.738 | 1.021 | 3.860 | 3.322 | 0.310 | 3.653 | 4.068 |
| 1990-01-03 | 0.266 | 4.000 | 4.636 | 0.161 | 4.910 | 14.364 | 1.121 | 3.452 | 3.508 | 2.203 | 6.658 | 4.282 | 0.386 | 4.692 | 1.024 | 3.853 | 3.322 | 0.304 | 3.653 | 4.027 |
| 1990-01-04 | 0.267 | 3.938 | 4.537 | 0.159 | 4.847 | 14.283 | 1.128 | 3.459 | 3.522 | 2.192 | 6.621 | 4.215 | 0.397 | 4.646 | 1.041 | 3.777 | 3.322 | 0.301 | 3.634 | 3.987 |
| 1990-01-05 | 0.268 | 3.812 | 4.438 | 0.159 | 4.775 | 14.148 | 1.113 | 3.423 | 3.536 | 2.174 | 6.549 | 4.128 | 0.387 | 4.581 | 1.032 | 3.709 | 3.322 | 0.288 | 3.595 | 3.966 |
| 1990-01-08 | 0.269 | 3.812 | 4.463 | 0.147 | 4.820 | 14.229 | 1.102 | 3.481 | 3.536 | 2.220 | 6.549 | 4.181 | 0.393 | 4.664 | 1.023 | 3.777 | 3.322 | 0.282 | 3.644 | 4.027 |
asset_linear_returns = prices_to_returns(price)
asset_linear_returns.head()
| AAPL | AMD | BAC | BBY | CVX | GE | HD | JNJ | JPM | KO | LLY | MRK | MSFT | PEP | PFE | PG | RRC | UNH | WMT | XOM | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | ||||||||||||||||||||
| 1990-01-03 | 0.007576 | -0.030303 | 0.008045 | 0.118056 | -0.016229 | -0.001876 | 0.003581 | 0.004072 | 0.033589 | -0.014318 | 0.000000 | 0.015896 | 0.005208 | -0.009709 | 0.002938 | -0.001813 | 0.0 | -0.019355 | 0.000000 | -0.010079 |
| 1990-01-04 | 0.003759 | -0.015500 | -0.021355 | -0.012422 | -0.012831 | -0.005639 | 0.006244 | 0.002028 | 0.003991 | -0.004993 | -0.005557 | -0.015647 | 0.028497 | -0.009804 | 0.016602 | -0.019725 | 0.0 | -0.009868 | -0.005201 | -0.009933 |
| 1990-01-05 | 0.003745 | -0.031996 | -0.021821 | 0.000000 | -0.014855 | -0.009452 | -0.013298 | -0.010408 | 0.003975 | -0.008212 | -0.010874 | -0.020641 | -0.025189 | -0.013991 | -0.008646 | -0.018004 | 0.0 | -0.043189 | -0.010732 | -0.005267 |
| 1990-01-08 | 0.003731 | 0.000000 | 0.005633 | -0.075472 | 0.009424 | 0.005725 | -0.009883 | 0.016944 | 0.000000 | 0.021159 | 0.000000 | 0.012839 | 0.015504 | 0.018118 | -0.008721 | 0.018334 | 0.0 | -0.020833 | 0.013630 | 0.015381 |
| 1990-01-09 | -0.007435 | 0.016527 | 0.000000 | 0.000000 | -0.007469 | -0.020803 | -0.026316 | -0.031026 | -0.031957 | -0.007658 | -0.011147 | -0.007893 | -0.002545 | -0.013722 | -0.021505 | 0.000000 | 0.0 | -0.024823 | -0.026619 | -0.020114 |
X_train, X_test = train_test_split(asset_linear_returns, shuffle=False)
X_test.head()
| AAPL | AMD | BAC | BBY | CVX | GE | HD | JNJ | JPM | KO | LLY | MRK | MSFT | PEP | PFE | PG | RRC | UNH | WMT | XOM | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | ||||||||||||||||||||
| 2014-09-29 | -0.006353 | -0.013889 | -0.001183 | 0.021517 | -0.007574 | -0.008196 | 0.000421 | -0.005226 | -0.003803 | 0.001190 | -0.002136 | 0.000347 | 0.000649 | 0.000207 | 0.001677 | -0.001653 | 0.014331 | -0.001042 | -0.005356 | -0.010485 |
| 2014-09-30 | 0.006394 | -0.039437 | 0.002369 | -0.001782 | -0.010200 | 0.007874 | -0.012268 | 0.000464 | -0.001493 | 0.009698 | -0.007512 | -0.002199 | -0.001721 | -0.000635 | -0.006698 | -0.008292 | -0.012518 | -0.002997 | 0.005132 | -0.004013 |
| 2014-10-01 | -0.015594 | -0.017595 | -0.013486 | -0.028875 | -0.013996 | -0.017960 | -0.007849 | -0.021480 | -0.007796 | 0.001859 | 0.003552 | -0.009603 | -0.009920 | -0.004724 | -0.014230 | -0.007156 | -0.005323 | -0.015893 | -0.004585 | -0.012653 |
| 2014-10-02 | 0.007266 | 0.011940 | 0.003594 | 0.003063 | -0.004596 | -0.001590 | 0.013405 | -0.004310 | -0.008934 | -0.001856 | -0.003836 | 0.002389 | -0.003054 | -0.000763 | -0.003068 | -0.001090 | 0.007563 | 0.000242 | 0.001441 | 0.004734 |
| 2014-10-03 | -0.002778 | 0.002950 | 0.024294 | 0.019871 | 0.005126 | 0.011145 | 0.014090 | 0.012316 | 0.024827 | 0.007963 | 0.012947 | 0.017827 | 0.007215 | 0.009944 | 0.005499 | 0.008914 | -0.017500 | 0.013185 | 0.014306 | 0.006647 |
Model#
Create a Maximize Sharpe Ratio model and fit it on training set.
max_sharpe_model = MeanRisk(
risk_measure=RiskMeasure.STANDARD_DEVIATION,
objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
portfolio_params=dict(name="Max Sharpe Ratio"),
)
max_sharpe_model.fit(X_train)
max_sharpe_model.weights_
array([9.12639732e-02, 2.85049328e-08, 2.31977012e-08, 1.04246239e-01,
3.08020521e-02, 3.60047992e-08, 4.18252122e-02, 1.72210429e-01,
4.01080513e-08, 7.82855158e-03, 8.14858866e-08, 8.52061207e-08,
1.12788995e-01, 7.13632483e-02, 2.64892622e-07, 1.10516792e-01,
7.81272384e-02, 1.75517534e-01, 2.39852902e-07, 3.50893616e-03])
benchmark_model = InverseVolatility(
portfolio_params=dict(name="Inverse Volatility")
)
benchmark_model.fit(X_train)
benchmark_model.weights_
array([0.03309451, 0.02507122, 0.03536272, 0.02895846, 0.06352572,
0.05434978, 0.04758711, 0.07073444, 0.03891936, 0.06692204,
0.05564459, 0.05576718, 0.04704164, 0.0638535 , 0.05597692,
0.06760446, 0.02585011, 0.03990667, 0.0577429 , 0.06608667])
Prediction#
The predict method returns a portfolio object.
pred_max_sharpe = max_sharpe_model.predict(X_test)
pred_benchmark = benchmark_model.predict(X_test)
pred_max_sharpe
<Portfolio Max Sharpe Ratio>
pred_benchmark
<Portfolio Inverse Volatility>
Print some properties.
print(pred_max_sharpe.returns)
print(pred_benchmark.returns)
print(pred_max_sharpe.annualized_sharpe_ratio)
print(pred_benchmark.annualized_sharpe_ratio)
[ 0.00136218 -0.00294776 -0.01437361 ... 0.0082964 0.00104224
-0.01662141]
[-0.00206867 -0.00293476 -0.01046662 ... 0.0086359 0.00202183
-0.0113165 ]
0.9684677102652403
0.8930043602505584
pred_max_sharpe.plot_cumulative_returns()
pred_benchmark.plot_cumulative_returns()